// JavaScript Document
function TimeChart(chartDOM, config) {
	// private:
	var backupData = null;
	var chart = new google.visualization.AnnotatedTimeLine(chartDOM);
	var chartOptions = { 'displayAnnotations': true, 'displayRangeSelector': false, 'allowHtml': true};
	
	var dataStore = new google.visualization.DataTable();
	dataStore.addColumn('date', 'Date');			// a particular day
	dataStore.addColumn('number', 'Views');		// # of views for a day
	dataStore.addColumn('string', 'title1');	// title of the review
	dataStore.addColumn('string', 'text1');		// description of the review
	
	this.update = function(data) {
		backupData = [];
		var prevDate = null;
		for (var i = 0, row = 0; i < data.length; i++, row++) {
			var dateParts = data[i].date.split('-');
			var date = new Date(dateParts[0], dateParts[1] - 1, dateParts[2]);
			
			// Fill in gaps between previous date and this date.
			if (prevDate) {
				var betweenDates = TimeChart.getBetweenDates(prevDate, date);
				for (var len = betweenDates.length, j = 0; j < len; j++) {
					dataStore.addRows([[betweenDates[j], 0, null, null]]);
					row++;
				}
			} else {  // first date
				// Add an extra day before the first date on timeline.
				dataStore.addRows([[new Date(date.getTime() - TimeChart.dayInMilliseconds), 0, null, null]]);
				row++;
			}
			prevDate = date;
			
			// Add link to title.
			if (data[i].title) {
				if (config && config.link) {
					data[i].title = '<a href="' + config.link.replace('{id}', data[i].id) + '">' + data[i].title + '</a>';
				}
				backupData.push([data[i].personid, row, data[i].title, data[i].desc]);
			}
			// The month of the Date object starts at 0
			dataStore.addRows([[date, data[i].views, data[i].title, data[i].desc]]);
		}
		// Add extra days to the end of timeline.
		dataStore.addRows([[new Date(prevDate.getTime() + TimeChart.dayInMilliseconds), 0, null, null]]);
		dataStore.addRows([[new Date(), 0, null, null]]);
		chart.draw(dataStore, chartOptions);
	}
	
	this.filterByPeople = function(peopleIds) {
		// Linear parsing filter, slow when a lot of markers present.
		var showAll = peopleIds.length == 0;
		for (var i = 0; i < backupData.length; i++) {
			var dataRow = backupData[i];
			if (showAll || peopleIds.indexOf(dataRow[0]) != -1) {
				dataStore.setCell(dataRow[1], 2, dataRow[2]);
				dataStore.setCell(dataRow[1], 3, dataRow[3]);
			} else {
				dataStore.setCell(dataRow[1], 2, null);
				dataStore.setCell(dataRow[1], 3, null);
			}
		}
		chart.draw(dataStore, chartOptions);
	}
}

// static members and methods
TimeChart.dayInMilliseconds = 1000 * 60 * 60 * 24;
TimeChart.getBetweenDates = function(start, end) {
	start = start.getTime() + TimeChart.dayInMilliseconds;
	end = end.getTime() - TimeChart.dayInMilliseconds;
	if (end < start) {  // difference is less than a day
		return [];
	} else if (Math.abs(end - start) < TimeChart.dayInMilliseconds) {  // differ by one day
		return [new Date(start)];
	} else {  // differ by two or more days
		return [new Date(start), new Date(end)];
	}
}
